package com.effectiv.crm.etl.impl;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import javax.inject.Named;

import jodd.bean.BeanUtil;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.BeanUtils;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.support.ConversionServiceFactory;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.util.ReflectionUtils;

import com.effectiv.crm.domain.FileUploadDetails;
import com.effectiv.crm.etl.api.TransformStrategy;

@Slf4j
@Named
public class CsvTransformStrategy implements TransformStrategy{
	
	private final String acceptedTypes[] = { "text/comma-separated-values",
			"text/csv", "application/csv" };
	
	@Override
	public List transform(List data, FileUploadDetails fileDetails, Class c) {
		
		log.info("Starting to transform rows");
		
		List l = new ArrayList();
		
		for(Object o : data){
			Object t = mapRow((String)o, fileDetails.getColumns(), fileDetails.getDelimiter(), c);
			
			l.add(t);
		}
		
		return l;
	
	}
	
	private Object mapRow(String line, String[] columns, char delimiter, Class c) {
		String elements [] = StringUtil.split(line, delimiter+"");
		Object o = null;
		
		log.info("Elements = {}",elements);
		
		if(elements != null){
			o = BeanUtils.instantiate(c);
			
			int index = 0;
			String col = null;
			
			GenericConversionService conversionService = ConversionServiceFactory.createDefaultConversionService();
			
			for(String e : elements){
				col = columns[index];
				
				if(!StringUtil.equals(col, "none")){
					Field f = ReflectionUtils.findField(c, col);
					
					Object value = conversionService.convert(e, new TypeDescriptor(f));
					
					log.info("Column name : {} , Value : {}",col,value);
					
					BeanUtil.setDeclaredPropertySilent(o, col, value);
				}
				
				index++;
			}
			
			
		}
		return o;
	}

	@Override
	public boolean canTransform(FileUploadDetails fileDetails) {
		return StringUtil.equalsOneIgnoreCase(fileDetails.getContentType(),
				acceptedTypes) != -1;
	}

	

}
